#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

extern char **environ;
/*#define CPU_INFO_DBG*/
#ifdef CPU_INFO_DBG
#define CPU_DEBUG(args...) printf(args)
#else
#define CPU_DEBUG(args...)
#endif
#include "cpu_cmd.h"
#include "cpu_info.h"
//对exec中函数的封装，避免重复代码
int get_cpu_info(ENUM_CPU_INFO en_cpu_info, char result[1024], int cpu_num)
{
    char cmd[1024];
    ENUM_COMMAND en_cmd = en_command_cat;
	memset(result, 0 ,1024);

    sprintf((char *)cmd, "%s%s%d%s%s", CMD_LIST[en_cmd],
            SYS_CPU_PATH, cpu_num, CMD_CAT_CPU_FREQ, CPU_INFO_LIST[en_cpu_info]);
    /*CPU_DEBUG("cmd is %s\n", cmd);*/

    return execute_cmd(cmd, result);
}

//获取cpu核心数
int get_cpu_num(void)
{
	char result[1024];
    const char cmd[1024] = "cat /sys/devices/system/cpu/possible";
    if(execute_cmd(cmd, result) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return result[2] - '0' + 1;
    }
	else{
		int error_num = errno;
		perror("get_cpu_num error");
		return error_num;
	}
}

/*获取影响到的cpu，没有用到，因为文件夹
*sys/devices/system/cpu/cpu0/cpufreq/
*里面有这个文件所以都实现了，后面没有用到的函数都是这个原因
*/
int get_affected_cpus(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_affected_cpus;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_affected_cpus error");
		return error_num;
	}
}

//获取bios对cpu最大频率的限制
int get_bios_limit(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_bios_limit;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_bios_limit error");
		return error_num;
	}
}

//获取所给cpu号的当前频率
int get_cpuinfo_cur_freq(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_cpuinfo_cur_freq;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_cpuinfo_cur_freq error");
		return error_num;
	}
}

//获取所给cpu号的最大频率
int get_cpuinfo_max_freq(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_cpuinfo_max_freq;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_cpuinfo_max_freq error");
		return error_num;
	}
}

//获取所给cpu号的最小频率
int get_cpuinfo_min_freq(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_cpuinfo_min_freq;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_cpuinfo_min_freq error");
		return error_num;
	}
}

//无用
int get_cpuinfo_transition_latency(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_cpuinfo_transition_latency;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_cpuinfo_transition_latency error");
		return error_num;
	}
}

//无用
int get_freqdomain_cpus(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_freqdomain_cpus;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_freqdomain_cpus error");
		return error_num;
	}
}

//无用
int get_related_cpus(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_related_cpus;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_related_cpus error");
		return error_num;
	}
}

//获取所给cpu号可以运行的频率
int get_scaling_available_frequences(char result[1024],int cpu_num)
{
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_available_frequencies;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %s\n", __func__, result);
		return 0;
    }
	else{
		int error_num = errno;
		perror("get_scaling_available_frequences error");
		return error_num;
	}
}

//获取所给cpu号可以使用的调度方法
int get_scaling_available_governors(char result[1024], int cpu_num)
{
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_available_governors;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %s\n", __func__, result);
		return 0;
    }
	else{
		int error_num = errno;
		perror("get_scaling_available_governors error");
		return error_num;
	}
}

//获取所给cpu号的当前频率，与get_cpuinfo_cur_freq差不多，后面用的此方法
int get_scaling_cur_freq(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_cur_freq;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_scaling_cur_freq error");
		return error_num;
	}
}

//获取cpu的控制驱动
int get_scaling_driver(char result[1024], int cpu_num)
{
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_driver;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %s\n", __func__, result);
		return 0;
    }
	else{
		int error_num = errno;
		perror("get_scaling_driver error");
		return error_num;
	}
}

//获取所给cpu号的当前的调度方法
int get_scaling_governor(char result[1024], int cpu_num)
{
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_governor;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %s\n", __func__, result);
		return 0;
    }
	else{
		int error_num = errno;
		perror("get_scaling_governor error");
		return error_num;
	}
}

//获取所给cpu号的最大频率与get_cpuinfo_max_freq差不多，后面用的此方法
int get_scaling_max_freq(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_max_freq;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_scaling_max_freq error");
		return error_num;
	}
}

//获取所给cpu号的最小频率与get_cpuinfo_min_freq差不多，后面用的此方法
int get_scaling_min_freq(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_min_freq;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_scaling_min_freq error");
		return error_num;
	}
}

//获取用户设置的频率
int get_scaling_setspeed(int cpu_num)
{
	char result[1024];
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_scaling_setspeed;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s: %d\n", __func__, atoi(result));
		return atoi(result);
    }
	else{
		int error_num = errno;
		perror("get_scaling_setspeed error");
		return error_num;
	}
}

//无用
int get_time_in_state(char result[1024], int cpu_num)
{
    ENUM_CPU_INFO en_cpu_info_l = en_cpu_info_time_in_state;
    if(get_cpu_info(en_cpu_info_l, result, cpu_num) >= 0){
		CPU_DEBUG("%s:\n %s", __func__, result);
		return 0;
    }
	else{
		int error_num = errno;
		perror("get_time_in_state error");
		return error_num;
	}
}

//设置cpu的调度方法
int set_cpu_governor(const char governor[1024], int cpu_num)
{
    char cmd[1024];
	char result[1024];
    sprintf((char *)cmd, "echo %s > %s%d%s%s", governor,
            SYS_CPU_PATH, cpu_num, CMD_CAT_CPU_FREQ, CPU_INFO_LIST[en_cpu_info_scaling_governor]);
    CPU_DEBUG("cmd is %s\n", cmd);

    return execute_cmd(cmd, result);
}

//设置cpu的最大频率，无用
int set_scaling_max_freq(int max_freq, int cpu_num)
{
    char cmd[1024];
	char result[1024];
    sprintf((char *)cmd, "echo %d > %s%d%s%s", max_freq,
            SYS_CPU_PATH, cpu_num, CMD_CAT_CPU_FREQ, CPU_INFO_LIST[en_cpu_info_scaling_max_freq]);
    CPU_DEBUG("cmd is %s\n", cmd);

    return execute_cmd(cmd, result);
}

//设置cpu的最小频率，无用
int set_scaling_min_freq(int min_freq, int cpu_num)
{
    char cmd[1024];
	char result[1024];
    sprintf((char *)cmd, "echo %d > %s%d%s%s", min_freq,
            SYS_CPU_PATH, cpu_num, CMD_CAT_CPU_FREQ, CPU_INFO_LIST[en_cpu_info_scaling_min_freq]);
    CPU_DEBUG("cmd is %s\n", cmd);

    return execute_cmd(cmd, result);
}

//设置cpu频率
int set_scaling_setspeed(int set_freq, int cpu_num)
{
    char cmd[1024];
	char result[1024];
    sprintf((char *)cmd, "echo %d > %s%d%s%s", set_freq,
            SYS_CPU_PATH, cpu_num, CMD_CAT_CPU_FREQ, CPU_INFO_LIST[en_cpu_info_scaling_setspeed]);
    CPU_DEBUG("cmd is %s\n", cmd);

    return execute_cmd(cmd, result);
}
